const { Student, Score, ImportLog, sequelize } = require('../models');
const excelService = require('./excelService');
const validationService = require('./validationService');
const fs = require('fs').promises;

/**
 * 导入服务
 */
class ImportService {
  /**
   * 导入 Excel 文件
   * @param {string} filePath - 文件路径
   * @param {string} filename - 文件名
   * @param {string} examName - 考试名称
   * @param {string} examDate - 考试日期
   * @returns {Object} 导入结果
   */
  async importExcelFile(filePath, filename, examName, examDate) {
    let transaction;
    
    try {
      // 1. 解析 Excel 文件
      const parsedData = excelService.parseExcelFile(filePath);
      
      // 2. 验证数据
      const validationResult = validationService.validateBatch(parsedData);
      
      // 3. 开始数据库事务
      transaction = await sequelize.transaction();
      
      // 4. 导入有效数据
      const importedCount = await this.importValidRecords(
        validationResult.validRecords,
        examName,
        examDate,
        transaction
      );
      
      // 5. 记录导入日志
      const importLog = await this.createImportLog({
        filename,
        totalRecords: validationResult.summary.total,
        successRecords: importedCount,
        failedRecords: validationResult.summary.invalid,
        errorDetails: validationResult.invalidRecords,
        status: this.determineStatus(importedCount, validationResult.summary.invalid)
      }, transaction);
      
      // 6. 提交事务
      await transaction.commit();
      
      // 7. 删除临时文件
      await this.cleanupFile(filePath);
      
      return {
        success: true,
        data: {
          importId: importLog.id,
          totalRecords: validationResult.summary.total,
          successRecords: importedCount,
          failedRecords: validationResult.summary.invalid,
          errors: validationResult.invalidRecords
        }
      };
      
    } catch (error) {
      // 回滚事务
      if (transaction) {
        await transaction.rollback();
      }
      
      // 删除临时文件
      await this.cleanupFile(filePath);
      
      throw error;
    }
  }

  /**
   * 导入有效记录
   * @param {Array} records - 有效记录数组
   * @param {string} examName - 考试名称
   * @param {string} examDate - 考试日期
   * @param {Transaction} transaction - 数据库事务
   * @returns {number} 导入数量
   */
  async importValidRecords(records, examName, examDate, transaction) {
    let importedCount = 0;
    
    for (const record of records) {
      try {
        // 创建或更新学生信息
        await Student.upsert({
          student_id: record.studentId,
          name: record.name,
          class_name: record.className
        }, { transaction });
        
        // 创建成绩记录
        await Score.create({
          student_id: record.studentId,
          exam_name: examName,
          exam_date: examDate,
          chinese: record.chinese,
          math: record.math,
          english: record.english,
          physics: record.physics,
          chemistry: record.chemistry,
          biology: record.biology,
          politics: record.politics,
          history: record.history,
          geography: record.geography,
          total_score: record.totalScore,
          school_rank: record.schoolRank
        }, { transaction });
        
        importedCount++;
      } catch (error) {
        console.error(`导入记录失败 (行 ${record.row}):`, error.message);
        // 继续处理下一条记录
      }
    }
    
    return importedCount;
  }

  /**
   * 创建导入日志
   * @param {Object} logData - 日志数据
   * @param {Transaction} transaction - 数据库事务
   * @returns {Object} 导入日志记录
   */
  async createImportLog(logData, transaction) {
    // 限制错误详情的数量，避免超出数据库字段限制
    const maxErrors = 100;
    const limitedErrors = logData.errorDetails.slice(0, maxErrors);
    
    return await ImportLog.create({
      filename: logData.filename,
      total_records: logData.totalRecords,
      success_records: logData.successRecords,
      failed_records: logData.failedRecords,
      error_details: limitedErrors,
      status: logData.status
    }, { transaction });
  }

  /**
   * 确定导入状态
   * @param {number} successCount - 成功数量
   * @param {number} failedCount - 失败数量
   * @returns {string} 状态
   */
  determineStatus(successCount, failedCount) {
    if (failedCount === 0) {
      return 'success';
    } else if (successCount === 0) {
      return 'failed';
    } else {
      return 'partial';
    }
  }

  /**
   * 清理临时文件
   * @param {string} filePath - 文件路径
   */
  async cleanupFile(filePath) {
    try {
      await fs.unlink(filePath);
    } catch (error) {
      console.error('删除临时文件失败:', error.message);
    }
  }
}

module.exports = new ImportService();
